import { Injectable, NestInterceptor, ExecutionContext, CallHandler, StreamableFile, HttpStatus } from "@nestjs/common";
import { Reflector } from "@nestjs/core";
import { Response } from "express";
import { Observable } from "rxjs";
import { map } from "rxjs/operators";
import { MyResponse } from "src/common/model";
import { EXCLUDE_TRANSFORM_KEY } from "src/constant";
import { isObject } from "@nestjs/common/utils/shared.utils";

@Injectable()
export class ResponseTransformInterceptor implements NestInterceptor {
    constructor(private reflector: Reflector) {}

    intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
        const isExclude = this.reflector.getAllAndOverride<boolean>(EXCLUDE_TRANSFORM_KEY, [
            context.getHandler(),
            context.getClass(),
        ]);

        if (isExclude) return next.handle();

        const statusCode = context.switchToHttp().getResponse<Response>().statusCode ?? HttpStatus.OK;

        return next.handle().pipe(
            map((data) => {
                if (!isObject(data) || data instanceof StreamableFile) {
                    return data;
                }
                return new MyResponse(statusCode, data);
            }),
        );
    }
}
